from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtGui import QPainter, QColor
from PyQt6.QtCore import QRectF, Qt
import math
import sys

class ColorWheel(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(200, 200)
        self.setMouseTracking(True)
        self.m_hoveredSector = -1
        self.m_selectedSector = -1
        self.m_init = True
        self.m_lastSelect = -1

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        rect = QRectF(10, 10, 180, 180)
        startAngle = [90, 210, 330]
        spanAngle = [120, 120, 120]
        colors = [QColor("red"), QColor("green"), QColor("blue")]

        x = self.width() / 4
        y = self.height() / 4
        w = self.width() / 2
        h = self.height() / 2
        innerRect = QRectF(x, y, w, h)

        # Ensure only redraw the necessary area
        painter.setClipRect(event.rect())

        if self.m_init:
            painter.setPen(colors[0])
            painter.setBrush(Qt.BrushStyle.NoBrush)
            painter.drawPie(rect, startAngle[0] * 16, spanAngle[0] * 16)

            painter.setPen(Qt.PenStyle.NoPen)
            painter.setBrush(QColor(255, 255, 255))
            painter.drawEllipse(innerRect)

            painter.setPen(colors[0])
            painter.drawArc(innerRect, startAngle[0] * 16, spanAngle[0] * 16)

        for i in range(3):
            if self.m_hoveredSector == i or self.m_selectedSector == i:
                painter.setPen(colors[i])
                painter.setBrush(Qt.BrushStyle.NoBrush)
                painter.drawPie(rect, startAngle[i] * 16, spanAngle[i] * 16)

                painter.setPen(Qt.PenStyle.NoPen)
                painter.setBrush(QColor(255, 255, 255))
                painter.drawEllipse(innerRect)

                painter.setPen(colors[i])
                painter.drawArc(innerRect, startAngle[i] * 16, spanAngle[i] * 16)

                self.m_lastSelect = self.m_selectedSector
            else:
                painter.setPen(colors[i].darker())
                painter.setBrush(Qt.BrushStyle.NoBrush)

        if not self.m_init and (self.m_selectedSector == -1):
            painter.setPen(colors[self.m_lastSelect])
            painter.setBrush(Qt.BrushStyle.NoBrush)
            painter.drawPie(rect, startAngle[self.m_lastSelect] * 16, spanAngle[self.m_lastSelect] * 16)

            painter.setPen(Qt.PenStyle.NoPen)
            painter.setBrush(QColor(255, 255, 255))
            painter.drawEllipse(innerRect)

            painter.setPen(colors[self.m_lastSelect])
            painter.drawArc(innerRect, startAngle[self.m_lastSelect] * 16, spanAngle[self.m_lastSelect] * 16)

        self.m_init = False

    def mousePressEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()
        sector = self.getSector(x, y)

        if sector != self.m_selectedSector:
            self.m_selectedSector = sector
            self.update()
            if sector >= 0 and sector < 3:
                color = [QColor("red"), QColor("green"), QColor("blue")][sector]
                print(f"Selected sector {sector}, color is {color.name()}")

    def getSector(self, x, y):
        dx = x - self.width() / 2
        dy = y - self.height() / 2
        r = math.sqrt(dx * dx + dy * dy)
        if r < self.width() / 4:
            angle = math.atan2(dy, dx) * 180 / math.pi
            if angle < 0:
                angle += 360
            sector = int(angle / 120)
            return sector
        return -1

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = ColorWheel()
    w.show()
    sys.exit(app.exec())
